Passed
Push — master ( 8c35a9...e9e480 )
by Plamen
01:56
created

table.js ➔ ... ➔ .Export   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 9
c 2
b 0
f 0
nc 2
nop 2
dl 0
loc 10
rs 9.95
1
var TableHelper = {
2
    BuildRequest: {
3
        Sort: function (rq, strDesc){
4
            function sortBySpan(span, i){
5
                var order = span.innerHTML;
6
                if(order.length === 1){
7
                    rq.colNo = i;
8
                    rq.colOrd = order === strDesc ? "desc" : "asc";
9
                }
10
                return rq.colNo === i;
11
            }
12
13
            var thTags = document.getElementById(rq.tableId)
14
                    .getElementsByTagName("thead")[0]
15
                    .getElementsByTagName("th");
16
            var length = thTags.length;
17
            for(var i = 0; i < length; i++){
18
                var link = thTags[i].getElementsByTagName("a")[0];
19
                if(link){
20
                    var span = link.getElementsByTagName("span")[0];
21
                    if(span && sortBySpan(span, i)){
22
                        break;
23
                    }
24
                }
25
            }
26
        },
27
        Filter: function (rq){
28
            function getFilterFieldsByTableID(tableID){
29
                var fields = {filterBy: null, filter: null};
30
                var filterDiv = getFilterDivByTableIDOrNull(tableID);
31
                if(filterDiv !== null){
32
                    setFilterBy(fields, filterDiv);
33
                    setFilterValue(fields, filterDiv);
34
                }
35
                return fields;
36
            }
37
            function getFilterDivByTableIDOrNull(tableID){
38
                var res = null;
39
                if(document.getElementById(tableID).parentNode.getElementsByTagName("div").length > 0){
40
                    for(var i = 0; i < document.getElementById(tableID).parentNode.getElementsByTagName("div").length; i++){
41
                        if(document.getElementById(tableID).parentNode.getElementsByTagName("div")[i].getAttribute("class") === "filter"){
42
                            return document.getElementById(tableID).parentNode.getElementsByTagName("div")[i];
43
                        }
44
                    }
45
46
                }
47
                return res;
48
            }
49
            function setFilterBy(fields, filterDiv){
50
                var slctObj = filterDiv.getElementsByTagName("select")[0];
51
                if(slctObj && slctObj.options[slctObj.selectedIndex].value !== "all"){
52
                    fields.filterBy = slctObj.options[slctObj.selectedIndex].value;
53
                }
54
            }
55
            function setFilterValue(fields, filterDiv){
56
                var textObj = filterDiv.getElementsByTagName("input")[0];
57
                if(textObj && textObj.value && textObj.value.length !== 0){
58
                    fields.filter = encodeURIComponent(textObj.value.trim());
59
                }
60
            }
61
62
            var r = getFilterFieldsByTableID(rq.tableId);
63
            if(r.filter !== null){
64
                rq.filter = r.filter;
65
            }
66
            if(r.filterBy !== null){
67
                rq.filterBy = r.filterBy;
68
            }
69
        },
70
        Run: (function(rq, crntTableId, strDesc){
71
            rq.tableId = crntTableId;
72
            TableHelper.BuildRequest.Sort(rq, strDesc);
73
            TableHelper.BuildRequest.Filter(rq);
74
        })
75
    },
76
    ColumnHover: function(tableContainer, index){
77
        var rows = document.getElementById(tableContainer).rows;
78
        var upto = rows.length - 1;
79
        if(typeof index === "undefined"){
80
            ColumnHoverRelease(rows, upto);
81
        } else {
82
            for(var i = 0; i < upto; i++){
83
                rows[i].cells[index].setAttribute("lang", "col-hover");
84
            }
85
        }
86
        function ColumnHoverRelease(rows, upto){
87
            for(var i = 0; i < upto; i++){
88
                for(var j = 0; j < rows[i].cells.length; j++){
89
                    if(rows[i].cells[j].lang){
90
                        rows[i].cells[j].removeAttribute("lang");
91
                    }
92
                }
93
            }
94
        };
95
    },
96
    Draw: {
97
        Section: function(tableContainer, dt, tSection){
98
            var section = tSection === "tfoot" ? "tfoot" : "tbody";
99
            var tSec = document.getElementById(tableContainer)
100
                        .getElementsByTagName(section)[0];
101
            Clear(tSec, TableHelper.IePrior(9));
102
            for(var i = 0; i < dt.length; i++){
103
                var row = dt[i];
104
                var tRow = document.createElement("tr");
105
                Row(row, tRow);
106
                tSec.appendChild(tRow);
107
                if(section === "tfoot"){
108
                    TableHelper.ProcessPaginationLinks(tSec);
109
                }
110
            }
111
            function Clear(tSection, iePrior9){
112
                if(iePrior9){
113
                    if(tSection.firstChild){
114
                        while(tSection.firstChild){
115
                            tSection.removeChild(tSection.firstChild);
116
                        }
117
                    }
118
                }else{
119
                    tSection.innerHTML = "";
120
                }
121
            }
122
            function Row(row, tRow){
123
                for(var cell in row){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
124
                    var tCell = document.createElement("td");
125
                    if(typeof row[cell] === "string" || typeof row[cell] === "number"){
126
                        tCell.innerHTML = row[cell];
127
                    }else if(typeof row[cell] === "object"){
128
                        RowCellFromObject(row, cell, tCell);
129
                    }
130
                    tRow.appendChild(tCell);
131
                }
132
            }
133
            function RowCellFromObject(row, cell, tCell){
134
                for(var attr in row[cell]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
135
                    if(typeof row[cell][attr] === "string"){
136
                        tCell.innerHTML = row[cell][attr];
137
                    }else if(typeof row[cell][attr] === "object"){
138
                        for(var v in row[cell][attr]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
139
                            tCell.setAttribute(v, row[cell][attr][v]);
140
                        }
141
                    }
142
                }
143
            }
144
        },
145
        Run: function(tableContainer, d, instance){
146
            this.Section(tableContainer, d.body);
147
            this.Section(tableContainer, d.footer, "tfoot");
148
            if(instance.rq !== null){
149
                var hover = document.getElementById(instance.rq.tableId)
150
                            .getElementsByTagName("th")[instance.rq.colNo].lang;
151
                if(hover){
152
                    instance.ColumnHover(tableContainer, instance.rq.colNo);
153
                }
154
            }
155
        }
156
    },
157
    Export: function(lnk, eType, strDesc){
158
        var request = {};
159
        var crntTableId = TableHelper.GetParent(lnk, "table").getAttribute("id");
160
        TableHelper.BuildRequest(request, crntTableId, strDesc);
161
        request.exportType = ["CSV", "Excel"].indexOf(eType) >= 0 ?
162
                                        eType : 
163
                                        "csv";
164
        window.open(TableHelper.RequestToUrl(request));
165
        return false;
166
    },
167
    Filter: {
168
        Run: function(field, instance, rq, strDesc){
169
            var crntTableId = TableHelper.Filter.GetTableId(field);
170
            if(crntTableId !== null){
171
                var request = {};
172
                var exRq = rq;
173
                TableHelper.BuildRequest.Run(request, crntTableId, strDesc);
174
                if(exRq === null ||
175
                    request.filter !== exRq.filter ||
176
                    request.filterBy !== exRq.filterBy
177
                ){
178
                    TableHelper.LoadData.Run(crntTableId, request, instance);
179
                }
180
            }
181
        },
182
        GetTableId: function(field){
183
            if(field.tagName.toLowerCase() !== "select"){
184
                return field.getAttribute("data-table-id");
185
            }
186
            var f = field.parentNode.parentNode.getElementsByTagName("input")[0];
187
            return '' === f.value ? null : f.getAttribute("data-table-id");
188
        }
189
    },
190
    Init: {
191
        Run: function(tableId){
192
            var tContainer = document.getElementById(tableId);
193
            if(!TableHelper.IePrior(9)){
194
                TableHelper.Init.SetColumnsHoverEffect(tContainer, tableId);
195
            }
196
            var tfoot = tContainer.getElementsByTagName("tfoot")[0];
197
            TableHelper.ProcessPaginationLinks(tfoot);
198
        },
199
        SetColumnsHoverEffect: function (tContainer, tableId){
200
            var tHcells = tContainer.rows[0].cells;
201
            for(var i = 0; i < tHcells.length; i++){
202
                if(tHcells[i].firstChild.tagName === "A"){
203
                    tHcells[i].firstChild.setAttribute("onmouseover", "table.ColumnHover('" + tableId + "'," + i + ");");
204
                    tHcells[i].firstChild.setAttribute("onmouseout", "table.ColumnHover('" + tableId + "');");
205
                }
206
            }
207
        }
208
    },
209
    
210
    GoPage: {
211
        Run: function(lnk, instance, strDesc){
212
            var request = {};
213
            var crntTableId = TableHelper.GetParent(lnk, "table").getAttribute("id");
214
            TableHelper.BuildRequest.Run(request, crntTableId, strDesc);
215
            request.pageNo = TableHelper.GoPage.GetNo(lnk, crntTableId);
216
            TableHelper.LoadData.Run(crntTableId, request, instance);
217
            return false;  
218
        },
219
        GetNo: function(lnk, tableId){
220
            //check & serve pagination jump links
221
            var jumpDir = lnk.innerHTML.trim().substr(0, 1);
222
            if(jumpDir === "+" || jumpDir === "-"){
223
                var current = document.getElementById(tableId)
224
                                .querySelector("tfoot .paging .a").innerHTML;
225
                var jump = lnk.innerHTML.replace("K", "000").replace("M", "000000000");
226
                var jumpPage = (parseInt(current) + parseInt(jump));
227
                lnk.parentNode.setAttribute("data-page", jumpPage);
228
                lnk.style.transform = "none";
229
            }
230
            return lnk.parentNode.hasAttribute("data-page") ?
231
                    lnk.parentNode.getAttribute("data-page") :
232
                    lnk.innerHTML;
233
        }
234
    },
235
    LoadData: {
236
        tail: null,
237
        Run: function(tableContainer, rq, instance){
238
            var tail = TableHelper.LoadData.tail;
239
            if(tail!==null){ tail.abort();}
240
            TableHelper.LoadData.SetVisability(tableContainer, false);
241
            var xmlhttp = window.XMLHttpRequest ? 
242
                            new XMLHttpRequest() : //IE7+, Firefox, Chrome, Opera, Safari
243
                            new window.ActiveXObject("Microsoft.XMLHTTP");//IE6, IE5
244
            xmlhttp.onreadystatechange = function(){
245
                if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
246
                    var d = JSON.parse(xmlhttp.responseText);
247
                    TableHelper.Draw.Run(tableContainer, d, instance);
248
                    TableHelper.LoadData.SetVisability(tableContainer, true);
249
                    instance.LoadEndCalback(tableContainer);
250
                }
251
            };
252
            xmlhttp.open("GET", TableHelper.RequestToUrl(rq), true);
253
            xmlhttp.send();
254
            TableHelper.LoadData.tail = xmlhttp; //put at tail to can abort later previous request
255
        },
256
        SetVisability: function(tableContainer, flag){
257
            var tbl = document.getElementById(tableContainer);
258
            if(flag === true){
259
                tbl.style.filter = "none";
260
                tbl.style.opacity = "1";
261
                tbl.style.cursor = "auto";
262
            }else if(flag === false){
263
                tbl.style.filter = "blur(1px)";
264
                tbl.style.opacity = "0.8";
265
                tbl.style.cursor = "wait";
266
            }else{
267
                console.error("table error in the flag value");
268
            }
269
        }
270
    },
271
272
    IePrior: function(v){
273
        var rv = false;
274
        if(window.navigator.appName === 'Microsoft Internet Explorer'){
275
            var ua = window.navigator.userAgent;
276
            var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
277
            if(re.exec(ua) !== null){
278
                rv = parseFloat(RegExp.$1);
279
            }
280
            rv = rv < v ? true : false;
281
        }
282
        return rv;
283
    },
284
    GetParent: function(obj, objType){
285
        while(obj && obj.tagName !== objType.toUpperCase()){
286
            obj = obj.parentNode;
287
        }
288
        return obj;
289
    },
290
    ProcessPaginationLinks: function(tfoot){
291
        var pLinks = tfoot.querySelectorAll(".paging a");
292
        if(pLinks.length > 0){
293
            for(var j = 0; j < pLinks.length; j++){
294
                pLinks[j].setAttribute("href", "javascript:void(0);");
295
                pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
296
            }
297
        }
298
    },
299
    RequestToUrl: function(rq){
300
        var url = location.pathname + ".json" + location.search;
301
        if(typeof rq === "object"){
302
            var getUrlVarName = {
303
                colNo: "col", colOrd: "ord", filter: "filter",
304
                filterBy: "filter-by", pageNo: "pg", exportType: "export",
305
                tableId: "table-id"
306
            };
307
            var flagFirst = location.search.length < 1 ? true : false;
308
            for(var r in rq){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
309
                var clue = flagFirst === true ? "?" : "&";
310
                url += clue + getUrlVarName[r] + "=" + rq[r];
311
                flagFirst = false;
312
            }
313
        }
314
        return url;
315
    }
316
};
317
318
//https://addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript
319
var TableSingleton = (function(){
320
    // Instance stores a reference to the Singleton
321
    var instance;
322
    function initInstance(){
323
        // Singleton
324
        // Private methods and variables
325
        var BuildRequest = TableHelper.BuildRequest.Run;
326
        var LoadData = TableHelper.LoadData.Run;
327
        function ReloadData(tableId){
328
            var request = {};
329
            BuildRequest(request, tableId, this.strDesc);
330
            LoadData(tableId, request, instance);
331
        }
332
        var GoPageGetNo = TableHelper.GoPage.GetNo;
0 ignored issues
show
Unused Code introduced by
The variable GoPageGetNo seems to be never used. Consider removing it.
Loading history...
333
        var GetParent = TableHelper.GetParent;
334
        var RequestToUrl = TableHelper.RequestToUrl;
0 ignored issues
show
Unused Code introduced by
The assignment to variable RequestToUrl seems to be never used. Consider removing it.
Loading history...
335
        var Init = TableHelper.Init.Run;
336
        function Export(lnk, eType){
337
            TableHelper.Export(lnk, eType, this.strDesc);   
338
        }
339
        function Filter(field){
340
            TableHelper.Filter.Run(field, instance, this.rq, this.strDesc);
341
        }
342
        function GoPage(lnk){
343
            TableHelper.GoPage.Run(lnk, instance, this.strDesc);
344
        }
345
346
        return {
347
            rq: null,
348
            strAsc: String.fromCharCode(9650), //&#9650;
349
            strDesc: String.fromCharCode(9660),//&#9660; 
350
            ColumnHover: TableHelper.ColumnHover, //function(tableContainer, index)
351
            Export: Export,
352
            Filter: Filter,
353
            GoPage: GoPage,
354
            init: Init,
355
            LoadEndCalback: function(){},/*Allows override: function(tableId){if(tableId){...}}*/
356
            ReloadData: ReloadData,
357
            Sort: function(colNo, lnk){
358
                var request = {};
359
                var crntTableId = GetParent(lnk, "table").getAttribute("id");
360
                BuildRequest(request, crntTableId, this.strDesc);
361
                if(Math.round(colNo) === request.colNo){
362
                    request.colOrd = (request.colOrd === "asc" ? "desc" : "asc");
363
                }else{
364
                    request.colNo = Math.round(colNo);
365
                    request.colOrd = "asc";
366
                }
367
                LoadData(crntTableId, request, instance);
368
                /* Clear and add new sort arrow */
369
                var headSpans = GetParent(lnk, "thead").getElementsByTagName("span");
370
                var length = headSpans.length;
371
                for(var i = 0; i < length; i++){
372
                    headSpans[i].innerHTML = "";
373
                }
374
                lnk.getElementsByTagName("span")[0].innerHTML = (request.colOrd === "desc" ? this.strDesc : this.strAsc);
375
            }
376
        };
377
    }
378
    return {
379
        //Get the Singleton instance if one exists, or create one if it doesn't
380
        getInstance: function(){
381
            if(!instance){
382
                instance = initInstance();
383
            }
384
            return instance;
385
        }
386
    };
387
})();
388
var table = TableSingleton.getInstance();
389